<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Dotfiles</title>
<link rel="shortcut icon" href="/csh/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" type="text/css" href="/csh/stylesheet.css"/>
</head>

<body>
<header>
  <p><a href="/csh"><img src="/csh/homeicon" alt="csh"/></a></p>
</header>

<h1>Organizing Public and Private Dotfiles for GNU Stow and Public Version Control</h1>
<p>
  I <em>suck</em> at backing up.  For once, I'd like to be able to
  download all my important stuff, run a single command, and have
  everything up and running.  I've
  seen <a href="https://dotfiles.github.io/">many dotfile management
  schemes</a>,
  including <a href="https://github.com/wking/dotfiles-framework">dotfiles.sh</a>
  and <a href="https://github.com/lra/mackup">Mackup</a>, but they all
  seem just a little bit over-engineered for my tastes.  In general, I
  prefer
  the <a href="http://brandon.invergo.net/news/2012-05-26-using-gnu-stow-to-manage-your-dotfiles.html">Stow
    method</a>.</p>
<p>
  The only problem with using GNU Stow for this is that I can't really
  keep private files separate, and I certainly can't keep passwords
  out of files that demand to keep them alongside all the intersting
  settings that are worth sharing.  To solve this, I will keep a
  single Stow package for all private files, and
  a <abbr title="Comma-Separated Values">CSV</abbr> file containing
  key-vlaue pairs for all private strings, which be applied and
  reverted with a simple search-and-replace mechanism before each
  deployment and publication.</p>
<p>
  This text should describe what's important to me, and how it will be
  structured in a backup.</p>

<h2>What's Important</h2>
<p>
  There are two categories of important things: public, and private.</p>
<h3>Public</h3>
<ul>
  <li>Bash configs</li>
  <li>Emacs configs</li>
  <li>Personal Emacs Lisp</li>
  <li>Personal shell scripts</li>
  <li>tmux config</li>
  <li>X resources</li>
  <li>Fonts</li>
  <li>Themes</li>
</ul>
<h3>Private</h3>
<ul>
  <li><abbr title="Secure Shell">SSH</abbr> keys</li>
  <li><abbr title="GNU Privacy Guard">GPG</abbr> keys</li>
  <li>Password store, for <a href="https://www.passwordstore.org/"><samp>pass</samp></a></li>
  <li>Contacts</li>
  <li>Work records</li>
</ul>

<h2>The Layout</h2>
<p>
  I scribbled a mockup of the layout of my dotfiles on paper last
  night.  It now looks something like this:</p>
<pre>
dotfiles/
  emacs/
    .emacs
  git/
    .gitconfig
  ssh/
    .ssh/
      id_rsa.pub
      known_hosts
  private.tar.gz.gpg
    .gnupg/
      ...
    .password-store/
      calher/
        matrix/
          pass.gpg
        ...
      csh/
        bluehome/
          pass.gpg
        roaming-initiative/
          pass.gpg
        sdf/
	  pass.gpg
	notabug/
	  pass.gpg
      calRedditFLOSSyourJS/
        reddit/
	  pass.gpg
      CharlieBrown/
        freenode/
          pass.gpg
	freepost/
	  pass.gpg
    .ssh/
      id_rsa
    substitutions.csv
      sha256sum password hash,base64 password cleartext
      0693a3a41b7bda5568f205cc000bff5f3bf917f65535b721ae273b3a956ea0b5,UGFzc3dvcmQxCg==
</pre>
<p>
  Perhaps the most peculiar item in this listing is the
  file <samp>substitutions.csv</samp>.  This is a list of
  corresponding strings for a search-and-replace program to use when
  adding or removing private information to otherwise public files.
  For example, if I wanted to put the
  passphrase <samp>Password1</samp> in my <samp>.gitconfig</samp>, I
  would add the following line after the <samp>[sendemail]</samp>
  section.</p>
<pre>
        smtppass = 0693a3a41b7bda5568f205cc000bff5f3bf917f65535b721ae273b3a956ea0b5
</pre>
<p>
  This would be put in the public copy of <samp>.gitconfig</samp>.
  After replacing all the strings and applying it to the running
  system, however, the same line would show the more legible
  passphrase, <samp>Password1</samp>.</p>
<pre>
smtppass = Password1
</pre>
<p>
  This should work with any file.  I doubt many programs would need me
  to escape characters in passphrases.</p>

<h2 id="deployment">Deployment</h2>
<p>
  The <a href="#deployment">#deployment</a> of the files should be as
  simple as cloning the repo, stowing the packages into the home
  directory where they belong, and replacing all the private strings
  mentioned in <samp>substitutions.csv</samp>.</p>
<pre>
git clone https://notabug.org/csh/dotfiles
cd dotfiles
stow tmux bash emacs git ssh
gpg -d private.tar.gz.gpg
tar -xvf private.tar.gz
stow private
private/expose-strings
</pre>
<p>
  <samp>expose-strings</samp> searches every file in
  the <samp>dotfiles/</samp> directory for the first cell of a line
  in <samp>substitutions.csv</samp>, <samp>base64</samp>-decodes the
  second cell of a line in the file, and puts the result in place of
  every found instance of the contents of the first cell of a
  line.</p>
<p>
  <samp>hide-strings</samp> will undo all of this, returning the
  hashes to their original places.  It will be run before every commit
  and upload.  Hopefully, version control will not notice.</p>

<h2 id="publishing">Publishing</h2>
<p>
  In order to do the <a href="#publishing">#publishing</a> of any new
  changes made in version control, and put them in public view on the
  Internet, we must ensure that <samp>private/</samp>
  and <samp>private.tar.gz</samp> are erased so they do not get
  tracked or committed.  In addition, <samp>hide-strings</samp> must
  be run so that passwords don't show up in public files either.  Only
  then can changes be committed and pushed to version control.</p>
<p>
  An example shell script might look like the following.</p>
<pre>
#!/bin/sh
cd ~/dotfiles/

# Disconnect private/
rm private.tar.gz private.tar.gz.gpg
stow -d private

# Update private/
tar -cvzf private.tar.gz private
gpg -c private.tar.gz

# Purge everything
./private/hide-strings
rm -r private/ private.tar.gz 

# Push
# No git commit; do manually in Emacs VC/Bash beforehand
git push

</pre>

  
<hr/>
<footer>
<p>Last updated: 2017-10-11 18:51:43 CDT.</p>
<p>
Copyright 2017 Caleb Herbert under the terms of the
<a href="https://creativecommons.org/licenses/by/4.0/">Attribution
4.0 International</a> license.</p>
</footer>
</body>
</html>
